import json
import time
import datetime
from PIL import Image
import numpy as np
from root.email_util import sendEmailWithFile
from root.get_data_from_dfcf import get_daily, get_minutes, get_all_stock
from root.img_util import grapImage, compareImg
from root.robot_mouse import RobotMouse


def init_py():
    print("启动交易系统")
    with open("mk_records/stock/init.json", 'r', encoding="utf-8") as f:
        res = json.loads(f.read())
    RobotMouse().execute_record(res)
    time.sleep(5)
    td = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
    now_screen = grapImage("mk_records/stock/py_records/" + td + "_init.png")
    ok_py = Image.open("mk_records/stock/index.png")
    ok_py = np.array(ok_py.getdata(), np.uint8).reshape(ok_py.size[1], ok_py.size[0], 3)
    ok_same = compareImg(now_screen, ok_py)
    print(ok_same)
    if ok_same > 0.9:
        print("ok")
        return 1
    else:
        print("not_ok")
        with open("mk_records/stock/login.json", 'r', encoding="utf-8") as f:
            res = json.loads(f.read())
        RobotMouse().execute_record(res)
    time.sleep(30)
    print("重置交易系统完成")


def exit_py():
    print("退出交易系统")
    with open("mk_records/stock/exit.json", 'r', encoding="utf-8") as f:
        res = json.loads(f.read())
    RobotMouse().execute_record(res)


def close_tip():
    res = []
    press = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 1100,
        "y": 620,
        "press": True,
        "info": "全仓按钮"
    }
    release = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 1100,
        "y": 620,
        "press": False
    }
    res.append(press)
    res.append(release)
    RobotMouse().execute_record(res)


# 判断是否交易日
def is_stock_day(date=''):
    date = date if date != '' else datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d")
    okflag = datetime.datetime.now().weekday()
    return okflag < 5


# 判断是否交易时间
def is_stock_time(dt=''):
    dt = dt[0:16] if dt != '' else datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M")
    if is_stock_day(dt[0:10]):
        if '09:30' < dt[11:16] < '11:30' or '13:00' < dt[11:16] < '15:00':
            return True
    return False


def buy_stock(code, many=0, price=0):
    init_py()
    print("开始交易,购入" + str(code) + "股票" + str(many) + "股")
    res = []
    with open("mk_records/stock/buy.json", 'r', encoding="utf-8") as f:
        res = json.loads(f.read())
    code_arr = [int(x) for x in str(code)]
    many_arr = [int(x) for x in str(many)]
    op_arr = []
    ind = 16  # 根据前面有几个操作更改
    for i in code_arr:
        press = {
            "type": "k",
            "delay": 1,
            "key": str(i),
            "vk": False,
            "press": True
        }
        release = {
            "type": "k",
            "delay": 0.1,
            "key": str(i),
            "vk": False,
            "press": False
        }
        op_arr.append(press)
        op_arr.append(release)
        res.insert(ind, press)
        res.insert(ind + 1, release)
        ind = ind + 2
    ind = ind + 2
    if many > 0:
        for j in many_arr:
            press = {
                "type": "k",
                "delay": 1,
                "key": str(j),
                "vk": False,
                "press": True
            }
            release = {
                "type": "k",
                "delay": 0.1,
                "key": str(j),
                "vk": False,
                "press": False
            }
            op_arr.append(press)
            op_arr.append(release)
            res.insert(ind, press)
            res.insert(ind + 1, release)
            ind = ind + 2
    else:
        press = {
            "type": "m",
            "delay": 1,
            "op": "c",
            "button": "l",
            "x": 250,
            "y": 350,
            "press": True,
            "info": "全仓按钮"
        }
        release = {
            "type": "m",
            "delay": 1,
            "op": "c",
            "button": "l",
            "x": 250,
            "y": 350,
            "press": False
        }
        res.insert(ind, press)
        res.insert(ind + 1, release)
        ind = ind + 2

    # 对方最优价确保交易成交
    press = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 230,
        "press": True,
        "info": "全仓按钮"
    }
    release = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 230,
        "press": False
    }
    res.insert(ind, press)
    res.insert(ind + 1, release)
    ind = ind + 2
    press = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 280,
        "press": True,
        "info": "全仓按钮"
    }
    release = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 280,
        "press": False
    }
    res.insert(ind, press)
    res.insert(ind + 1, release)

    print(res)

    RobotMouse().execute_record(res)
    time.sleep(5)
    td = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
    pypath = "mk_records/stock/py_records/" + td + "_" + str(code) + "_" + str(many) + ".png"
    now_screen = grapImage(pypath)
    ok_py = Image.open("mk_records/stock/ok_py.png")
    ok_py = np.array(ok_py.getdata(), np.uint8).reshape(ok_py.size[1], ok_py.size[0], 3)
    ok_same = compareImg(now_screen, ok_py)
    print(ok_same)
    if ok_same > 0.9:
        print("交易成功")
        exit_py()
        return 1, pypath
    else:
        print("交易失败")
        exit_py()
        return 0, pypath

    """
    not_py = Image.open("mk_records/stock/not_py.png")
    np.array(not_py.getdata(), np.uint8).reshape(not_py.size[1], not_py.size[0], 3)
    if compareImg(now_screen, not_py) > 0.9:
        RobotMouse().execute_record(res)
        print("不是交易日")
        return
    """


def sell_stock(code, many=0, price=0):
    init_py()
    print("开始交易,卖出" + str(code) + "股票" + str(many) + "股")
    res = []
    with open("mk_records/stock/sell.json", 'r', encoding="utf-8") as f:
        res = json.loads(f.read())
    code_arr = [int(x) for x in str(code)]
    many_arr = [int(x) for x in str(many)]
    op_arr = []
    ind = 16  # 根据前面有几个操作更改
    for i in code_arr:
        press = {
            "type": "k",
            "delay": 1,
            "key": str(i),
            "vk": False,
            "press": True
        }
        release = {
            "type": "k",
            "delay": 0.1,
            "key": str(i),
            "vk": False,
            "press": False
        }
        op_arr.append(press)
        op_arr.append(release)
        res.insert(ind, press)
        res.insert(ind + 1, release)
        ind = ind + 2
    ind = ind + 2
    if many > 0:
        for j in many_arr:
            press = {
                "type": "k",
                "delay": 1,
                "key": str(j),
                "vk": False,
                "press": True
            }
            release = {
                "type": "k",
                "delay": 0.1,
                "key": str(j),
                "vk": False,
                "press": False
            }
            op_arr.append(press)
            op_arr.append(release)
            res.insert(ind, press)
            res.insert(ind + 1, release)
            ind = ind + 2
    else:
        press = {
            "type": "m",
            "delay": 3,
            "op": "c",
            "button": "l",
            "x": 250,
            "y": 350,
            "press": True,
            "info": "全仓按钮"
        }
        release = {
            "type": "m",
            "delay": 1,
            "op": "c",
            "button": "l",
            "x": 250,
            "y": 350,
            "press": False
        }
        res.insert(ind, press)
        res.insert(ind + 1, release)
        ind = ind + 2

    # 对方最优价确保交易成交
    press = {
        "type": "m",
        "delay": 3,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 230,
        "press": True,
        "info": "全仓按钮"
    }
    release = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 230,
        "press": False
    }
    res.insert(ind, press)
    res.insert(ind + 1, release)
    ind = ind + 2
    press = {
        "type": "m",
        "delay": 3,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 280,
        "press": True,
        "info": "全仓按钮"
    }
    release = {
        "type": "m",
        "delay": 1,
        "op": "c",
        "button": "l",
        "x": 350,
        "y": 280,
        "press": False
    }
    res.insert(ind, press)
    res.insert(ind + 1, release)

    print(res)

    RobotMouse().execute_record(res)
    time.sleep(5)
    td = datetime.datetime.now().strftime('%Y-%m-%d%H%M%S')
    pypath = "mk_records/stock/py_records/" + td + "_" + str(code) + "_" + str(many) + ".png"
    now_screen = grapImage(pypath)
    ok_py = Image.open("mk_records/stock/ok_py.png")
    ok_py = np.array(ok_py.getdata(), np.uint8).reshape(ok_py.size[1], ok_py.size[0], 3)
    ok_same = compareImg(now_screen, ok_py)
    print(ok_same)
    if ok_same > 0.9:
        print("交易成功")
        exit_py()
        return 1, pypath
    else:
        print("交易失败")
        exit_py()
        return 0, pypath


# 近期强势股低于5日买，高于5日卖
def auto_py_of_stock_avg(codes=[], day=5):
    for item in codes:
        code = item["market"] + "." + item["stkCode"]
        stock_data = get_daily(code)
        price_data = list(float(tup.split(",")[8]) for tup in stock_data)
        l = len(price_data) - 1
        addp = 0 if l < day else sum(price_data[l - day:l])
        if addp < 0:
            print(item["stkName"] + "：下穿" + str(day) + "日线")
            return False
        else:
            print(item["stkName"] + "：上穿" + str(day) + "日线")
            return True


# 日内成交量突然放大
def auto_py_of_stock_many(codes=[], price=1, many=10):
    for item in codes:
        code = item["market"] + "." + item["stkCode"]
        stock_data = get_minutes(code)
        dt = list(str(tup.split(",")[0]) for tup in stock_data)
        price_data = list(float(tup.split(",")[2]) for tup in stock_data)
        many_data = list(float(tup.split(",")[5]) for tup in stock_data)
        l = len(price_data)
        while 1 <= l <= len(price_data):
            l = l - 1
            addp = 0 if l < 1 or price_data[l - 1] == 0 else (price_data[l] - price_data[l - 1]) * 100 / price_data[
                l - 1]
            addm = 0 if l < 1 or many_data[l - 1] == 0 else many_data[l] / many_data[l - 1]
            if addp > price and addm > many:
                print(item["stkName"] + ":在" + dt[l - 1] + "：1分钟内上涨" + str(addp) + ",量比" + str(addm))
                return True
            elif addp < -price and addm > many:
                print(item["stkName"] + ":在" + dt[l - 1] + "：1分钟内下跌" + str(addp) + ",量比" + str(addm))
                return False
            # print(code + ":" + str(addp) + ":" + str(addm))


# 日内自动做T，5分钟下跌%3以上买入，5分钟上涨3%卖出,例如东方电缆
def auto_py_of_stock_t(codes=['603606'], price=1, minutes=5):
    for item in codes:
        code = item["market"] + "." + item["stkCode"]
        stock_data = get_minutes(code)
        price_data = list(float(tup.split(",")[2]) for tup in stock_data)
        dt = list(str(tup.split(",")[0]) for tup in stock_data)
        l = len(price_data)
        while 1 <= l <= len(price_data):
            l = l - 1
            addp = 0 if l < minutes or price_data[l - minutes] == 0 else (price_data[l] - price_data[
                l - minutes]) * 100 / price_data[l - minutes]
            if addp > price:
                print(item["stkName"] + ":在" + dt[l - minutes] + "：日内快速上涨" + str(addp))
                return True
            elif addp < -price:
                print(item["stkName"] + ":在" + dt[l - minutes] + "：日内快速下跌" + str(addp))
                return False


def print_day_stock_info():
    while True:
        stocks = get_all_stock()
        stocks = list(filter(lambda temp: 'ST' in temp['stkName'], stocks))
        stocks = list(filter(
            lambda temp: temp["stkCode"].find('600') == 0 or temp["stkCode"].find('601') == 0
                         or temp["stkCode"].find('602') == 0 or temp["stkCode"].find('603') == 0
                         or temp["stkCode"].find('002') == 0 or temp["stkCode"].find('000') == 0, stocks))
        print(stocks)
        auto_py_of_stock_avg(stocks)
        auto_py_of_stock_t(stocks, 2, 1)
        auto_py_of_stock_many(stocks, 2, 2)
        time.sleep(60)


if __name__ == '__main__':
    # 是否实盘
    isPy = False
    # 是否发邮件
    sendEmail = False
    # 单笔限额*100 10000就为100
    maxMoney = 100

    while True:
        td = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        stock_day = is_stock_day(td[0:10])
        stock_time = is_stock_time(td)
        print(td)
        print("当前是否交易日：" + str(stock_day))
        print("当前是否交易时间：" + str(stock_time))
        if stock_time:
            print('********auto-dfcf-py-start*******')
            last_op_date2 = ''
            operator_list2 = []
            try:
                with open("anyalse_result/dfcfpylog.json", 'r') as f:
                    operator_list2 = json.loads(f.read())
            except Exception as e:
                print(e)
            if len(operator_list2) > 0:
                last_op_date2 = operator_list2[len(operator_list2) - 1]["cjsj"]
            if last_op_date2 == '':
                last_op_date2 = td[0:10] + " 00:00:00"

            # 非实盘仅打印异动
            if isPy == False:
                #打印异动
                print_day_stock_info()

            # 实盘
            if isPy == True:
                #获取全部股票过滤
                stocks = get_all_stock()
                stocks = list(filter(lambda temp: 'ST' in temp["stkName"], stocks))
                stocks = list(filter(
                    lambda temp: temp["market"].find('600') == 0 or temp["market"].find('601') == 0
                                 or temp["market"].find('602') == 0 or temp["market"].find('603') == 0
                                 or temp["market"].find('002') == 0 or temp["market"].find('000') == 0, stocks))
                print(len(stocks))

                dfcf_py = []
                for op in stocks:
                    # 默认提供3种算法，选一种或者自己写都可以
                    # 近期强势股低于5日买，高于5日卖
                    # auto_py_of_stock_avg(codes=stocks, day=5)
                    # 日内成交量突然放大
                    # auto_py_of_stock_many(codes=stocks, price=1, many=10)
                    # 日内自动做T，5分钟下跌%3以上买入，5分钟上涨3%卖出,例如东方电缆
                    # auto_py_of_stock_t(codes=stocks, price=1, minutes=5)
                    flag = (0, '')
                    # 单笔交易限额10000
                    many = int(maxMoney / float(op["cjjg"]))
                    if auto_py_of_stock_avg(codes=list(op["stkCode"]), day=5) \
                            and auto_py_of_stock_many(codes=list(op["stkCode"]), price=1, many=10)\
                            and auto_py_of_stock_t(codes=list(op["stkCode"]), price=1, minutes=5):
                        flag = buy_stock(op["stkCode"], (many if many > 0 else 1) * 100)
                        op['op'] = '买入'
                    else:
                        flag = sell_stock(op["stkCode"], 0)
                        op['op'] = '卖出'
                    if flag[0] == 1:
                        print("交易成功")
                        dfcf_py.append(op)
                        if sendEmail:
                            sendEmailWithFile(
                                td + op['op'] + str(op["stkCode"]) + op["stkName"] + str(many * 100) + "股,单价" + str(
                                    op["cjjg"]) + "成功",
                                "自动交易成功",
                                flag[1])
                    else:
                        print("交易失败")
                        if sendEmail:
                            sendEmailWithFile(
                                td + op['op'] + str(op["stkCode"]) + op["stkName"] + str(many * 100) + "股,单价" + str(
                                    op["cjjg"]) + "失败",
                                "自动交易失败",
                                flag[1])

                    op["success"] = flag[0]
                    if len(dfcf_py) > 0:
                        operator_list2 = operator_list2 + dfcf_py
                        with open("anyalse_result/dfcfpylog.json", 'w') as f:
                            f.write(json.dumps(operator_list2))
        time.sleep(60)
